package middleware

import (
	"fmt"
	"net/http"
	"strings"
	"sync"
	"time"

	"gitee.com/wangshh_123/cross-pay-go/src/database"
	"gitee.com/wangshh_123/cross-pay-go/src/models"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/common"
	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
)

// PlatformInfo 平台信息结构体
type PlatformInfo struct {
	MatrixAccount       string        `json:"matrix_account"`                  // 矩阵账户号
	MatrixAccountName   string        `json:"matrix_account_name"`             // 矩阵账户名称
	PlatformType        string        `json:"platform_type"`                   // 平台类型
	Status              string        `json:"status"`                          // 状态
	TotalTransferAmount string        `json:"total_transfer_amount"`           // 总转账金额
	ParentMatrixAccount *PlatformInfo `json:"parent_matrix_account,omitempty"` // 父级矩阵账户信息
}

// Cache for platform information
var (
	platformInfoCache sync.Map
	cacheDuration     = 5 * time.Minute
)

// getParentPlatformInfo 获取父级平台信息
func getParentPlatformInfo(matrixAccount string) (*PlatformInfo, error) {
	if !strings.HasPrefix(matrixAccount, "SUB") {
		return nil, nil
	}

	var parentAccount models.UserMatrixAccount
	result := database.DB.Table("user_matrix_accounts").
		Joins("LEFT JOIN user_matrix_accounts parent ON parent.id = user_matrix_accounts.parent_matrix_account_id").
		Where("user_matrix_accounts.matrix_account = ? AND user_matrix_accounts.status = 'active'", matrixAccount).
		Select("parent.*").
		First(&parentAccount)

	if result.Error != nil {
		return nil, result.Error
	}

	// 转换为PlatformInfo结构
	parentInfo := &PlatformInfo{
		MatrixAccount:       parentAccount.MatrixAccount,
		MatrixAccountName:   parentAccount.MatrixAccountName,
		PlatformType:        parentAccount.PlatformType,
		Status:              parentAccount.Status,
		TotalTransferAmount: parentAccount.TotalTransferAmount.StringFixed(2),
	}

	return parentInfo, nil
}

// convertToPlatformInfo 将数据库模型转换为平台信息结构
func convertToPlatformInfo(account *models.UserMatrixAccount) *PlatformInfo {
	return &PlatformInfo{
		MatrixAccount:       account.MatrixAccount,
		MatrixAccountName:   account.MatrixAccountName,
		PlatformType:        account.PlatformType,
		Status:              account.Status,
		TotalTransferAmount: account.TotalTransferAmount.StringFixed(2),
	}
}

// PlatformInfoMiddleware 平台信息中间件
// 获取用户的矩阵账户信息和对应的平台类型
func PlatformInfoMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 从上下文中获取用户ID
		userID, exists := c.Get("user_id")
		if !exists {
			common.Error(c, http.StatusUnauthorized, "user_info_not_found", nil)
			c.Abort()
			return
		}

		fmt.Printf("[PlatformInfoMiddleware] 用户ID: %v\n", userID)

		// 清除缓存，确保每次都从数据库重新查询
		platformInfoCache.Delete(userID)

		// 从数据库查询
		var matrixAccount models.UserMatrixAccount
		result := database.DB.Where("user_id = ? AND status = 'active'", userID).First(&matrixAccount)

		if result.Error != nil {
			if result.Error.Error() == "record not found" {
				common.Error(c, http.StatusUnauthorized, "no_valid_matrix_account", nil)
			} else {
				common.Error(c, http.StatusInternalServerError, "query_matrix_account_failed", result.Error)
			}
			c.Abort()
			return
		}

		fmt.Printf("[PlatformInfoMiddleware] 从数据库查询到矩阵账户: MatrixAccount=%s, PlatformType=%s, Status=%s\n",
			matrixAccount.MatrixAccount, matrixAccount.PlatformType, matrixAccount.Status)

		// 检查账户状态
		if matrixAccount.Status != "active" {
			common.Error(c, http.StatusUnauthorized, "matrix_account_status_abnormal", nil)
			c.Abort()
			return
		}

		// 转换为平台信息结构
		platformInfo := convertToPlatformInfo(&matrixAccount)

		// 如果是SUB开头的账户，获取父级账户信息
		if strings.HasPrefix(matrixAccount.MatrixAccount, "SUB") {
			parentInfo, err := getParentPlatformInfo(matrixAccount.MatrixAccount)
			if err != nil {
				common.Error(c, http.StatusInternalServerError, "get_parent_matrix_account_failed", err)
				c.Abort()
				return
			}
			if parentInfo != nil {
				platformInfo.ParentMatrixAccount = parentInfo
			}
		}

		fmt.Printf("[PlatformInfoMiddleware] 转换后的平台信息: PlatformType=%s\n", platformInfo.PlatformType)

		// 更新缓存
		platformInfoCache.Store(userID, struct {
			PlatformInfo *PlatformInfo
			Expiry       time.Time
		}{
			PlatformInfo: platformInfo,
			Expiry:       time.Now().Add(cacheDuration),
		})

		// 将平台信息存储到上下文中
		c.Set("platform_info", platformInfo)
		c.Next()
	}
}

// GetPlatformInfoFromContext 从上下文中获取平台信息
func GetPlatformInfoFromContext(c *gin.Context) (*PlatformInfo, bool) {
	platformInfo, exists := c.Get("platform_info")
	if !exists {
		return nil, false
	}
	return platformInfo.(*PlatformInfo), true
}

// GetPlatformTypeFromContext 从上下文中获取平台类型
func GetPlatformTypeFromContext(c *gin.Context) (string, bool) {
	platformInfo, exists := GetPlatformInfoFromContext(c)
	if !exists {
		return "", false
	}
	return platformInfo.PlatformType, true
}

// GetMatrixAccountFromContext 从上下文中获取矩阵账户号
func GetMatrixAccountFromContext(c *gin.Context) (string, bool) {
	platformInfo, exists := GetPlatformInfoFromContext(c)
	if !exists {
		return "", false
	}
	return platformInfo.MatrixAccount, true
}

// ClearPlatformInfoCache 清除指定用户的平台信息缓存
func ClearPlatformInfoCache(userID int64) {
	platformInfoCache.Delete(userID)
}

// ClearAllPlatformInfoCache 清除所有平台信息缓存
func ClearAllPlatformInfoCache() {
	platformInfoCache = sync.Map{}
}

// MatrixAccountMiddleware Matrix账户中间件（保持向后兼容）
// @deprecated 建议使用 PlatformInfoMiddleware 替代
func MatrixAccountMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 从上下文中获取用户ID
		userID, exists := c.Get("user_id")
		if !exists {
			common.Error(c, http.StatusUnauthorized, "user_info_not_found", nil)
			c.Abort()
			return
		}

		// 尝试从缓存获取
		if cached, ok := platformInfoCache.Load(userID); ok {
			cacheData := cached.(struct {
				PlatformInfo *PlatformInfo
				Expiry       time.Time
			})
			if time.Now().Before(cacheData.Expiry) {
				// 转换为旧的矩阵账户格式以保持兼容性
				// 将字符串转换回decimal.Decimal
				totalTransferAmount, _ := decimal.NewFromString(cacheData.PlatformInfo.TotalTransferAmount)
				matrixAccount := &models.UserMatrixAccount{
					MatrixAccount:       cacheData.PlatformInfo.MatrixAccount,
					MatrixAccountName:   cacheData.PlatformInfo.MatrixAccountName,
					PlatformType:        cacheData.PlatformInfo.PlatformType,
					Status:              cacheData.PlatformInfo.Status,
					TotalTransferAmount: totalTransferAmount,
				}
				c.Set("matrix_account_info", matrixAccount)
				c.Next()
				return
			}
		}

		// 缓存不存在或已过期，从数据库查询
		var matrixAccount models.UserMatrixAccount
		result := database.DB.Where("user_id = ? AND status = 'active'", userID).First(&matrixAccount)

		if result.Error != nil {
			if result.Error.Error() == "record not found" {
				common.Error(c, http.StatusUnauthorized, "no_valid_matrix_account", nil)
			} else {
				common.Error(c, http.StatusInternalServerError, "query_matrix_account_failed", result.Error)
			}
			c.Abort()
			return
		}

		// 检查账户状态
		if matrixAccount.Status != "active" {
			common.Error(c, http.StatusUnauthorized, "matrix_account_status_abnormal", nil)
			c.Abort()
			return
		}

		// 如果是SUB开头的账户，获取父级账户
		if strings.HasPrefix(matrixAccount.MatrixAccount, "SUB") {
			parentAccount, err := getParentMatrixAccount(matrixAccount.MatrixAccount)
			if err != nil {
				common.Error(c, http.StatusInternalServerError, "get_parent_matrix_account_failed", err)
				c.Abort()
				return
			}
			if parentAccount != nil {
				matrixAccount = *parentAccount
			}
		}

		// 更新缓存（使用新的平台信息格式）
		platformInfo := convertToPlatformInfo(&matrixAccount)
		platformInfoCache.Store(userID, struct {
			PlatformInfo *PlatformInfo
			Expiry       time.Time
		}{
			PlatformInfo: platformInfo,
			Expiry:       time.Now().Add(cacheDuration),
		})

		// 将Matrix账户信息存储到上下文中（保持向后兼容）
		c.Set("matrix_account_info", &matrixAccount)
		c.Next()
	}
}

// getParentMatrixAccount 获取父级矩阵账户（保持向后兼容）
func getParentMatrixAccount(matrixAccount string) (*models.UserMatrixAccount, error) {
	if !strings.HasPrefix(matrixAccount, "SUB") {
		return nil, nil
	}

	var parentAccount models.UserMatrixAccount
	result := database.DB.Table("user_matrix_accounts").
		Joins("LEFT JOIN user_matrix_accounts parent ON parent.id = user_matrix_accounts.parent_matrix_account_id").
		Where("user_matrix_accounts.matrix_account = ? AND user_matrix_accounts.status = 'active'", matrixAccount).
		Select("parent.*").
		First(&parentAccount)

	if result.Error != nil {
		return nil, result.Error
	}

	return &parentAccount, nil
}

// ClearMatrixAccountCache 清除指定用户的Matrix账户缓存（保持向后兼容）
func ClearMatrixAccountCache(userID int64) {
	ClearPlatformInfoCache(userID)
}
